package com.bestcem.xm.member.service.impl;

import cn.hutool.core.lang.ObjectId;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.member.dao.DisplayRangeDao;
import com.bestcem.xm.member.entity.pojo.DisplayRangeDO;
import com.bestcem.xm.member.enums.DisplayRangeTypeEnum;
import com.bestcem.xm.member.grpc.client.XmMemberClient;
import com.bestcem.xm.member.grpc.service.param.displayrange.CreateDisplayRangeParam;
import com.bestcem.xm.member.grpc.service.param.displayrange.GetDisplayRangeParam;
import com.bestcem.xm.member.grpc.service.param.displayrange.UpdateDisplayRangeParam;
import com.bestcem.xm.member.service.DisplayRangeService;
import com.bestcem.xm.member.service.dto.DisplayRangeDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dc.wang <dc.wang@idiaoyan.com>
 * @version V1.0
 * @description 联系人联系方式展示范围信息实现类
 * @date 2021/7/19
 */
@Slf4j
@Service
public class DisplayRangeServiceImpl implements DisplayRangeService {
    private final DisplayRangeDao displayRangeDao;

    @Autowired
    public DisplayRangeServiceImpl(DisplayRangeDao displayRangeDao) {
        this.displayRangeDao = displayRangeDao;
    }

    @Autowired
    private XmMemberClient xmMemberClient;

    @Override
    public @NotNull ServiceResult<DisplayRangeDto> getDisplayRange(@NotNull GetDisplayRangeParam getParam) {
        DisplayRangeDO displayRange = displayRangeDao.findByOrgAndMemberType(getParam.getOrgId(), getParam.getMemberType().getIndex());
        if (displayRange == null) {
            displayRange = new DisplayRangeDO();
            displayRange.setDisplayId(ObjectId.next());
            displayRange.setOrgId(getParam.getOrgId());
            displayRange.setMemberType(getParam.getMemberType().getIndex());
            displayRange.setType(getParam.getMemberType().getIndex());
            displayRange.setCreateTime(DateUtil.getCommonDate());
            displayRange.setUpdateTime(displayRange.getCreateTime());
            // 可见范围类型不存在，默认所有人可见
            displayRange.setRoleIds(JSONObject.toJSONString(new ArrayList<>()));

            displayRange = displayRangeDao.create(displayRange);
        }

        DisplayRangeDto displayRangeDto = this.convertFrom(displayRange);
        return ServiceResult.success(displayRangeDto);
    }

    @Override
    public @NotNull ServiceResult<DisplayRangeDto> createDisplayRange(@NotNull CreateDisplayRangeParam createParam) {
        DisplayRangeDO existedRange = displayRangeDao.findByOrgAndMemberType(createParam.getOrgId(), createParam.getMemberType().getIndex());
        if(existedRange != null){
            return ServiceResult.fail("展示范围已存在");
        }

        DisplayRangeDO displayRange = new DisplayRangeDO();
        displayRange.setDisplayId(ObjectId.next());
        displayRange.setOrgId(createParam.getOrgId());
        displayRange.setMemberType(createParam.getMemberType().getIndex());
        displayRange.setType(createParam.getType().value());
        displayRange.setCreateTime(DateUtil.getCommonDate());
        displayRange.setUpdateTime(displayRange.getCreateTime());

        // 管理员可见则保存当前企业管理员id集合
        if (DisplayRangeTypeEnum.ADMIN.equals(createParam.getType())) {
            ServiceResult<List<String>> result = xmMemberClient.listOrgAdminIds(createParam.getOrgId());
            if(!result.isSuccess() || CollectionUtils.isEmpty(result.getData())){
                log.error("查询企业管理员失败：{}, {}", createParam.getOrgId(), result.getMsg());
                return ServiceResult.fail("查询企业管理员id集合失败");
            }
            displayRange.setRoleIds(JSONObject.toJSONString(result.getData()));
        } else {
            // 可见范围类型不存在，默认所有人可见
            displayRange.setRoleIds(JSONObject.toJSONString(new ArrayList<>()));
        }

        DisplayRangeDO createdDisplayRange = displayRangeDao.create(displayRange);
        DisplayRangeDto displayRangeDto = this.convertFrom(createdDisplayRange);

        return ServiceResult.success(displayRangeDto);
    }

    @Override
    public @NotNull ServiceResult<DisplayRangeDto> updateDisplayRange(@NotNull UpdateDisplayRangeParam updateParam) {
        DisplayRangeDO displayRange = new DisplayRangeDO();
        displayRange.setOrgId(updateParam.getOrgId());
        displayRange.setMemberType(updateParam.getMemberType().getIndex());
        displayRange.setType(updateParam.getType().value());
        displayRange.setUpdateTime(DateUtil.getCommonDate());

        // 管理员可见则保存当前企业管理员id集合
        if (DisplayRangeTypeEnum.ADMIN.matches(updateParam.getType().value())) {
            ServiceResult<List<String>> result = xmMemberClient.listOrgAdminIds(updateParam.getOrgId());
            if(!result.isSuccess() || CollectionUtils.isEmpty(result.getData())){
                log.error("查询企业管理员失败：{}, {}", updateParam.getOrgId(), result.getMsg());
                return ServiceResult.fail("查询企业管理员id集合失败");
            }

            displayRange.setRoleIds(JSONObject.toJSONString(result.getData()));
        } else {
            // 可见范围类型不存在，默认所有人可见
            displayRange.setRoleIds(JSONObject.toJSONString(new ArrayList<>()));
        }

        DisplayRangeDO existedRange = displayRangeDao.findByOrgAndMemberType(updateParam.getOrgId(), updateParam.getMemberType().getIndex());
        if(existedRange == null){
            // 创建展示范围
            displayRange.setDisplayId(ObjectId.next());
            displayRange = displayRangeDao.create(displayRange);
        }else{
            displayRange.setDisplayId(existedRange.getDisplayId());
            displayRange = displayRangeDao.update(displayRange);
        }

        DisplayRangeDto displayRangeDto = this.convertFrom(displayRange);
        return ServiceResult.success(displayRangeDto);
    }

    /**
     * 类型转换
     * @param displayRange 展示范围信息
     * @return DTO对象
     */
    private DisplayRangeDto convertFrom(DisplayRangeDO displayRange) {
        DisplayRangeDto displayRangeDto = new DisplayRangeDto();
        displayRangeDto.setId(displayRange.getDisplayId());
        displayRangeDto.setOrgId(displayRange.getOrgId());
        displayRangeDto.setMemberType(displayRange.getMemberType());
        displayRangeDto.setType(displayRange.getType());
        if(StringUtils.hasText(displayRange.getRoleIds())){
            List<String> roleIds =
                    JSON.parseArray(displayRange.getRoleIds(), String.class);
            displayRangeDto.setRoleIds(roleIds);
        }
        return displayRangeDto;
    }

    /**
     * 是否隐藏 手机号与邮箱
     *
     * @param orgId
     * @param memberType
     * @param userId
     * @return
     */
    @Override
    public Boolean isDisplayContact(String orgId, Integer memberType, String userId) {
        // 从数据库中获取
        DisplayRangeDO displayRange = displayRangeDao.findByOrgAndMemberType(orgId, memberType);
        if (log.isInfoEnabled()) {
            log.info(" 该用户的权限{}", displayRange);
        }
        if (displayRange != null && DisplayRangeTypeEnum.ALL.matches(displayRange.getType())) {
            return true;
        }

        ServiceResult<List<String>> result = xmMemberClient.listOrgAdminIds(orgId);
        if (!result.isSuccess()) {
            log.error("检查用户是否有查看联系方式的权限校验失败 {}", result.getMsg());
            return false;
        }

        List<String> data = result.getData();
        if (log.isInfoEnabled()) {
            log.info("管理员id {}", data);
        }

        return !CollectionUtils.isEmpty(data) && data.contains(userId);
    }
}
